<script setup lang="ts">
import {ref, watch, computed, onBeforeMount} from "vue";
import _ from "lodash";
import {monthDay} from "@/util/timeUtil";
import {userConfigStore} from "@/store/user/userConfigStore";
import {loginConfigStore} from "@/store/user/loginConfigStore";
import {message} from "ant-design-vue";
import {CaretLeftOutlined, CaretRightOutlined, createFromIconfontCN} from "@ant-design/icons-vue"
import {iconFontAddress} from "@/util/commonUtil";

const props = defineProps({
  //第一列星期几
  weekStart: {
    type: Number,
    default: 7
  },
  //已经签到的日期
  signedDates: {
    type: Array<any>,
    default: null
  },
  chooseDates: {
    type: Array<any>,
    default: null
  },
  // 补签卡
  maxChoose: {
    type: Number,
    default: 0
  },
  //选择回调
  chooseCallBack: {
    type: Function,
    default() {
      return () => {
      };
    }
  },
  //是否展开
  open: {
    type: Boolean,
    default: true
  },
  //显示顶部
  showTop: {
    type: Boolean,
    default: true
  },
  //显示底部伸缩按钮
  showOpenBtn: {
    type: Boolean,
    default: true
  },
  //禁用点击事件
  unClick: {
    type: Boolean,
    default: false
  },
  calendarList: {
    type: Array<any>,
    default: null
  }
});
const text = ref<any>({
  year: "年",
  month: "月",
  week: ["一", "二", "三", "四", "五", "六", "日"],
  today: "今"
})
const y = ref<any>(new Date().getFullYear()) // 年
const m = ref<any>(new Date().getMonth() + 1) // 月
const dates = ref<any>([]) //当前月日期集合
const positionTop = ref<number>(0)
const monthOpen = ref<boolean>(true)
const canPrev = ref<boolean>(true)
const canNext = ref<boolean>(false)
const nextCount = ref<number>(0)
const calendarListDate = ref<any>(new Map())
const IconFont = createFromIconfontCN({
  scriptUrl: iconFontAddress,
});
const emit = defineEmits(['handlePrev', 'handleNext']);

onBeforeMount(() => {
  dates.value = monthDay(y.value, m.value, props.weekStart);
})
// 计算属性
const weekDay = computed(() => {
  return text.value.week
      .slice(props.weekStart - 1)
      .concat(text.value.week.slice(0, props.weekStart - 1));
});

watch(() => props.calendarList, () => {
  let tmpList = props.calendarList
  for (let i in tmpList) {
    //日期改变格式 2022-07-07  变为 2022-7-7
    let dateFormat = dislodgeZero(tmpList[i].date)
    if (tmpList[i].isOffDay == "false") {
      calendarListDate.value.set(dateFormat, '班')
    } else {
      calendarListDate.value.set(dateFormat, tmpList[i].name)
    }
  }
})

watch(()=>nextCount.value,()=>{
  canNext.value = m.value < new Date().getMonth() + 1;
})
/**
 * =======================================================*/
function dislodgeZero(str: string) {
  if (!_.isUndefined(str)) {
    let strArray = str.split("-");
    strArray = strArray.map(function (val) {
      if (val[0] == "0") {
        return (val.slice(1));
      } else {
        return val;
      }
    });
    return strArray.join("-");
  }
}

// 点击上一月
function clickPrev() {
  nextCount.value = nextCount.value - 1
  if (nextCount.value < -10) {
    nextCount.value = nextCount.value + 1
    canNext.value = true
    canPrev.value = false
    return
  } else {
    canNext.value = true
    canPrev.value = true
  }
  let year, lastMonth;
  let nowYear = y.value;   //当前年：四位数字
  let nowMonth = m.value;     //当前月：0-11
  if (nowMonth == 1) {   //如果是0，则说明是1月份，上一个月就是去年的12月
    year = nowYear - 1;
    lastMonth = 12;
  } else {
    year = nowYear;
    lastMonth = nowMonth - 1;
  }
  y.value = year
  m.value = lastMonth
  dates.value = monthDay(y.value, m.value, props.weekStart);
  cleanSelect()
  if (lastMonth < 10) {
    lastMonth = '0' + lastMonth;
  }
  let dateStr = year + "-" + (lastMonth)
  emit("handlePrev", dateStr);
}

// 点击下一月
function clickNext() {
  nextCount.value = nextCount.value + 1
  if (nextCount.value > 0){
    canNext.value = false
    canPrev.value = true
    nextCount.value = nextCount.value - 1
    return
  } else {
    canNext.value = true
    canPrev.value = true
  }
  let year, lastMonth;
  let nowYear = y.value;
  let nowMonth = m.value;
  if (nowMonth == 12) {   //如果是0，则说明是1月份，上一个月就是去年的12月
    year = nowYear + 1;
    lastMonth = 1;
  } else {
    year = nowYear;
    lastMonth = nowMonth + 1;
  }
  y.value = year
  m.value = lastMonth
  dates.value = monthDay(y.value, m.value, props.weekStart);
  if (lastMonth < 10) {
    lastMonth = '0' + lastMonth;
  }
  let dateStr = year + "-" + (lastMonth)
  cleanSelect()
  emit("handleNext", dateStr);
}

//已经签到处理
function isSigned(y: any, m: any, d: any) {
  if (m < 10) {
    m = '0' + m;
  }
  if (d < 10) {
    d = '0' + d;
  }
  let flag = false;
  for (let i = 0; i < props.signedDates.length; i++) {
    let dy = `${y}-${m}-${d}`;
    if (props.signedDates[i] == dy) {
      flag = true;
      break;
    }
  }
  return flag;
}

function cleanSelect() {
  let lists = document.getElementsByClassName("calendar-day");
  for (let i = 0; i < lists.length; i++) {
    lists[i].classList.remove("choose");
  }
}

function isToday(y: any, m: any, d: any) {
  let date = new Date();
  return (
      y == date.getFullYear() && m == date.getMonth() + 1 && d == date.getDate()
  );
}

//点击回调
function selectOne(i: any, event: any) {
  let isLogin = userConfigStore().isLogin
  if (!isLogin) {
    loginConfigStore().setLoginMessage(Math.random())
    return
  }
  if (!i.lm) {
    message.warning("无法选择该日期")
    return
  }
  let year = i.year;
  let month = i.month;
  let date = i.date;
  if (month < 10) {
    month = '0' + month;
  }
  if (month > 12) {
    message.warning("无法选择该日期")
    return false;
  }
  if (date > 31) {
    message.warning("无法选择该日期")
    return false;
  }
  if (isToday(i.year, i.month, i.date)) {
    message.warning("今日无需补签，请点击签到按钮")
    return false;
  }
  if (date < 10) {
    date = '0' + date;
  }
  let dy = year + '-' + month + '-' + date;
  let selectD = new Date(i.year, i.month - 1, i.date);
  let todayD = new Date();
  if (selectD > todayD || (selectD.getFullYear() >= todayD.getFullYear() &&
      selectD.getMonth() >= todayD.getMonth() + 1 && selectD.getDate() >= todayD.getDate()) || props.signedDates.includes(dy)) {
    message.warning("选择时间超过当前日期")
    return false;
  }
  //如果已存在就删除，不存在则添加
  let ind = props.chooseDates.findIndex(value => {
    return value == dy;
  });
  let parDom = event.srcElement.parentNode;
  if (ind === -1 && (props.chooseDates.length < props.maxChoose || props.maxChoose === 0)) {
    //超出限制
    if (props.chooseDates.length >= props.maxChoose) {
      message.warning("暂无补签卡，通过活跃用户排行榜每周会发放哟~")
      return false;
    }
    props.chooseDates.push(dy);
    parDom.classList.add("choose");
  } else if (ind > -1) {
    props.chooseDates.splice(ind, 1);
    parDom.classList.remove("choose");
  }
  //排序
  props.chooseDates.sort((a: any, b: any) => {
    return new Date(a).getTime() - new Date(b).getTime();
  });
  props.chooseCallBack(props.chooseDates);
}
</script>

<template>
  <div class="signCalendar relative flex flex-col gap-4 w-[576px] text-base text-black text-center bg-white mt-6 mb-2">
    <header class="calendarHeader leading-4 mb-4 flex justify-between" v-show="showTop">
      <div class="calendarData flex items-center">
        <a-button type="text" class="cursor-pointer" :disabled="!canPrev"
                  @click="clickPrev">
          <CaretLeftOutlined/>
        </a-button>
        <span>{{ y }}{{ text.year }}{{ m }}{{ text.month }}</span>
        <a-button type="text" class="cursor-pointer" :disabled="!canNext"
                  @click="clickNext">
          <CaretRightOutlined/>
        </a-button>
      </div>
      <div class="signInfo">
        <span class="mr-1">
          <IconFont type="icon-buqianka"/>
          补签卡:
        </span>
        <span class="text-orange-500 mr-1">{{ maxChoose }}</span>
        <span>张</span>
      </div>
    </header>
    <div class="week flex items-center h-4 leading-4 gap-[0.75rem] mb-1">
      <span class="week-day text-gray-400 flex-1" v-for="(item,index) in weekDay" :key="index">{{ item }}</span>
    </div>
    <div
        :class="{'hide' : !monthOpen}"
        class="content relative">
      <div :style="{ top : positionTop + 'px' }" class="days flex flex-wrap relative items-center">
        <span
            v-for="(item,index) in dates"
            :key="index"
            class="calendar-day relative flex justify-center items-center w-[72px] h-[68px] rounded mr-3 mb-4 cursor-pointer"
            :class="{
              nolm: !item.lm,
              signed:isSigned(item.year, item.month, item.date),
              today: isToday(item.year, item.month, item.date)
           }">
          <em class="flex items-center justify-center overflow-hidden w-full h-full text-base leading-[1rem] not-italic"
              @click.stop="!unClick ? selectOne(item,$event):''">{{ item.date }}</em>
          <i class="absolute not-italic w-[1.5rem] h-[1.5rem] bottom-[0.1rem] hidden right-[0.22rem]"></i>
          <b class="absolute top-[20%] not-italic text-[0.8rem] right-[20%] text-rose-500"
             v-if="isToday(item.year, item.month, item.date)">今</b>
          <span v-if="calendarListDate.get(item.year+'-'+item.month +'-'+ item.date)"
                class="festival">{{ calendarListDate.get(item.year + '-' + item.month + '-' + item.date) }}</span>
        </span>
      </div>
    </div>
  </div>
</template>

<style scoped lang="less">
:deep(.ant-btn.ant-btn-text) {
  display: flex;
  justify-content: center;
  align-items: center;
}

.calendar-day:not(.nolm) {
  background: #f2f3f6;
}

.content .days .calendar-day:nth-child(7n) {
  margin-right: 0;
}

.signCalendar {
  .content {
    transition: height 0.4s ease;

    .days {
      transition: top 0.3s;

      span {
        i {
          background: url("@/assets/task/signed.svg");
          background-size: 100% 100%;
        }
      }

      .choose {
        em {
          background-color: #9fcdff;
          color: #0157d8;
        }
      }

      .signed {
        em {
          background-color: #bae6fd;
          border-radius: 0.25rem;
        }

        i {
          display: block;
        }
      }

      .today {
        em {
          background-color: #e0f2fe;
          border-radius: 0.25rem;
          color: #0157d8;
        }
      }

      .nolm {
        em {
          color: #fff;
          opacity: 0.3;
        }
      }
    }
  }

  .hide {
    height: 40px;
  }
}

.festival {
  color: #FFDFDD;
  display: inline-block;
  width: 100%;
  position: relative;
  top: -53px;
  left: 0;
  height: 10px;
}
</style>
